package com.yunqiao.service.sys.impl;

import cn.hutool.core.date.DateUtil;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunqiao.common.consts.AppConsts;
import com.yunqiao.common.exception.CustomApiException;
import com.yunqiao.common.utils.Constant;
import com.yunqiao.common.utils.PageUtils;
import com.yunqiao.common.utils.Query;
import com.yunqiao.common.utils.SmsUtils;
import com.yunqiao.service.api.entity.ApplyPartnerEntity;
import com.yunqiao.service.api.entity.SysSmscodeEntity;
import com.yunqiao.service.api.entity.UserEntity;
import com.yunqiao.service.api.mapper.ApplyPartnerMapper;
import com.yunqiao.service.api.mapper.SysSmscodeMapper;
import com.yunqiao.service.api.mapper.UserMapper;
import com.yunqiao.service.sys.SysRoleService;
import com.yunqiao.service.sys.SysUserRoleService;
import com.yunqiao.service.sys.SysUserService;
import com.yunqiao.service.sys.entity.SysUserEntity;
import com.yunqiao.service.sys.entity.SysUserRoleEntity;
import com.yunqiao.service.sys.mapper.SysUserDao;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * 系统用户
 *
 * @author Crocutax
 * @email wangxw725@163.com
 * @date 2016年9月18日 上午9:46:09
 */
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
    @Autowired
    private SysUserDao sysUserDao;
	@Autowired
	private SysUserRoleService sysUserRoleService;
	@Autowired
	private SysRoleService sysRoleService;
    @Autowired
    private SysSmscodeMapper sysSmscodeMapper;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ApplyPartnerMapper applyPartnerMapper;


    @Override
	public PageUtils queryPage(Map<String, Object> params) {
		String username = (String)params.get("username");
		Long createUserId = (Long)params.get("createUserId");

//		Page<SysUserEntity> page = this.page(
//			new Query<SysUserEntity>(params).getPage(),
//			new QueryWrapper<SysUserEntity>()
//				.like(StringUtils.isNotBlank(username),"username", username)
//				.eq(createUserId != null,"create_user_id", createUserId)
//		);

        IPage<SysUserEntity> page = this.page(
				new Query<SysUserEntity>(params).getPage(),
				new QueryWrapper<SysUserEntity>()
						.like(StringUtils.isNotBlank(username),"username", username)
						//.eq(createUserId != null,"create_user_id", createUserId)
		);

		return new PageUtils(page);
	}

	@Override
	public List<String> queryAllPerms(Long userId) {
		return baseMapper.queryAllPerms(userId);
	}

	@Override
	public List<Long> queryAllMenuId(Long userId) {
		return baseMapper.queryAllMenuId(userId);
	}

	@Override
	public SysUserEntity queryByUserName(String username) {
		return baseMapper.queryByUserName(username);
	}

	@Override
	@Transactional
	public boolean save(SysUserEntity user) {
		user.setCreateTime(new Date());
		//sha256加密
		String salt = RandomStringUtils.randomAlphanumeric(20);
		user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
		user.setSalt(salt);
        this.sysUserDao.insert(user);

		//检查角色是否越权
		checkRole(user);

		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
		return true;
	}

	@Override
	@Transactional
	public void update(SysUserEntity user) {
		if(StringUtils.isBlank(user.getPassword())){
			user.setPassword(null);
		} else {
			user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
		}
		this.updateById(user);

		//检查角色是否越权
		checkRole(user);

		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
	}

	@Override
	public void deleteBatch(Long[] userId) {
		this.removeByIds(Arrays.asList(userId));
	}

	@Override
	public boolean updatePassword(Long userId, String password, String newPassword) {
		SysUserEntity userEntity = new SysUserEntity();
		userEntity.setPassword(newPassword);
		return this.update(userEntity, new QueryWrapper<SysUserEntity>().eq("user_id", userId).eq("password", password));
	}

    @Override
    public Boolean checkedSmsCode(String phone, String smsCode) {
        //获取最近的一条数据
        SysSmscodeEntity sysSmscodeEntity = sysSmscodeMapper.selectOne(new QueryWrapper<SysSmscodeEntity>()
            .eq("phone", phone)
            .apply(true, "created_at in (select max(created_at) from sys_smscode where phone = '"+phone+"')"));

        if (sysSmscodeEntity == null) {
            throw new CustomApiException("请获取验证码");
        }
        if (DateUtil.thisMinute() - DateUtil.minute(sysSmscodeEntity.getCreatedAt()) > 6) {
            throw new CustomApiException("你的验证码已过期,请在6分钟内发送");
        }
        if (!sysSmscodeEntity.getSmscode().equals(smsCode)) {
            throw new CustomApiException("验证码有误");
        }
        //验证成功，删除数据

        try {
            //成不成都通过，不影响逻辑
            sysSmscodeMapper.deleteById(sysSmscodeEntity.getId());
            return true;
        } catch (Exception e) {
            return true;
        }
    }

    @Override
    @Transactional
    public SysUserEntity createUser(Long id) throws ClientException {
        UserEntity userEntity = userMapper.selectById(id);
        SysUserEntity sysUserEntity = sysUserDao.selectOne(new QueryWrapper<SysUserEntity>().eq("username", userEntity.getPhone()));
        if (sysUserEntity == null) {
            sysUserEntity = new SysUserEntity();
            sysUserEntity.setUsername(userEntity.getPhone());
            sysUserEntity.setType(AppConsts.SYS_USER_TYPE_1);
            sysUserEntity.setSalt("YzcmCZNvbXocrsz9dm8e");
            sysUserEntity.setPassword("9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d");
            sysUserDao.insert(sysUserEntity);
            SysUserRoleEntity sysUserRoleEntity = new SysUserRoleEntity();
            sysUserRoleEntity.setUserId(sysUserEntity.getUserId());
            sysUserRoleEntity.setRoleId(AppConsts.ROLE_PARTNER_ID);
            sysUserRoleService.save(sysUserRoleEntity);
        }
        //修改代理商与申请表的关联
        ApplyPartnerEntity applyPartnerEntity = applyPartnerMapper.selectOne(new QueryWrapper<ApplyPartnerEntity>().eq("state", AppConsts.USER_APPLY_PARTNER_STATE_3)
            .eq("user_id", id));
        applyPartnerEntity.setSysUserId(sysUserEntity.getUserId());
        applyPartnerMapper.updateById(applyPartnerEntity);
        // 发送一条短信
        SmsUtils.sendPartner(userEntity.getPhone());
        return sysUserEntity;
    }

    /**
	 * 检查角色是否越权
	 */
	private void checkRole(SysUserEntity user){
		if(user.getRoleIdList() == null || user.getRoleIdList().size() == 0){
			return;
		}
		//如果不是超级管理员，则需要判断用户的角色是否自己创建
		if(user.getCreateUserId() == Constant.SUPER_ADMIN){
			return;
		}

		//查询用户创建的角色列表
//		List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());
//
//		//判断是否越权
//		if(!roleIdList.containsAll(user.getRoleIdList())){
//			throw new CustomApiException("新增用户所选角色，不是本人创建");
//		}
	}
}
